﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Engine.Graphics;
using Engine;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Engine.Helpers;

namespace Estadio.GameObjects.Helpers
{
    public class Handle : Entity, IContainController<Entity>
    {
        private IHandleController controller;

        #region IContainController<IController<Entity>> Members

        public IController<Entity> Controller
        {
            get { return controller; }
        }

        #endregion

        Entity handle, knob, limit;
        List<Entity> walls;

        public Handle(Entity handle, Entity knob, Entity limit, IHandleController controller, params Entity[] walls)
            : base(null)
        {
            this.controller = controller;
            this.controller.Target = handle;

            this.handle = handle;
            this.knob = knob;
            this.limit = limit;
            this.walls = walls.ToList();
        }

        public override void Update(GameTime gameTime)
        {
            float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

            // All is moved in local coordinates (local position, local rotation, local matrices).
            // But collision checking is done on the global transformation.

            Vector3 prevLocalPos = controller.Target.Position; // = handle.Position;
            Vector3 nextLocalPos = prevLocalPos + Vector3.UnitZ * controller.Move() * dt;

            handle.Position = nextLocalPos;
            knob.Position = nextLocalPos;
            limit.Position = nextLocalPos;

            bool isValid = true;
            foreach (var wall in walls)
            {
                BoundingBox wallBBox = wall.BoundingBox.Transform(wall.World);

                if (knob.BoundingBox.Transform(knob.World).Intersects(wallBBox) ||
                    limit.BoundingBox.Transform(limit.World).Intersects(wallBBox))
                {
                    isValid = false;
                    break;
                }
            }

            // Revert the movement.
            if (!isValid)
            {
                handle.Position = prevLocalPos;
                knob.Position = prevLocalPos;
                limit.Position = prevLocalPos;
            }

            // Rotate (always can rotate).
            controller.Target.Rotation *= Matrix.CreateRotationZ(dt * controller.Rotate());
            base.Update(gameTime);
        }
    

}
}
